{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 我是一个专为帮助人们提供信息和建议的大型语言模型，可以在多种场合和领域中工作。由于我的特点，可以非常快速地理解问题并回答用户提出的问题或提供相关建议。虽然我是一个机器人，但我试图尽力地模仿人类的思维和交互方式，以便于使用和理解。我的目标是成为你的可靠的信息资源和生活支持者！希望我能为您提供有帮助的建议或回答您提出的问题！\n"
     ]
    }
   ],
   "source": [
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url='http://localhost:11434/v1/',\n",
    "    # required but ignored\n",
    "    api_key='ollama',\n",
    ")\n",
    "chat_completion = client.chat.completions.create(\n",
    "    messages=[\n",
    "        {\n",
    "            'role': 'user',\n",
    "            'content': '你能介绍一下自己吗？',\n",
    "        }\n",
    "    ],\n",
    "    model='mistral',\n",
    ")\n",
    "\n",
    "# print(chat_completion)\n",
    "# print(chat_completion.choices)\n",
    "if(len(chat_completion.choices) > 0):\n",
    "    response = chat_completion.choices[0]\n",
    "    if response is not None:\n",
    "        msg = response.message\n",
    "        print(msg.content)\n",
    "# response = chat_completion['choices'][0]['text']\n",
    "# print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " The product of 123 and 456 is 56088.\n"
     ]
    }
   ],
   "source": [
    "### https://developer.aliyun.com/article/1490420\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.messages import HumanMessage, BaseMessage\n",
    "from langgraph.graph import END, MessageGraph\n",
    "import json\n",
    "from langchain_core.messages import ToolMessage\n",
    "from langchain_core.tools import tool\n",
    "from langchain_core.utils.function_calling import convert_to_openai_tool\n",
    "from typing import List\n",
    "\n",
    "import os\n",
    "os.environ[\"OPENAI_API_KEY\"] = \"ollama\"\n",
    "\n",
    "@tool\n",
    "def multiply(first_number: int, second_number: int):\n",
    "    \"\"\"Multiplies two numbers together.\"\"\"\n",
    "    return first_number * second_number\n",
    "\n",
    "model = ChatOpenAI(base_url=\"http://localhost:11434/v1/\", model=\"mistral\", temperature=0)\n",
    "model_with_tools = model.bind(tools=[convert_to_openai_tool(multiply)])\n",
    "graph = MessageGraph()\n",
    "\n",
    "def invoke_model(state: List[BaseMessage]):\n",
    "    return model_with_tools.invoke(state)\n",
    "\n",
    "graph.add_node(\"oracle\", invoke_model)\n",
    "\n",
    "def invoke_tool(state: List[BaseMessage]):\n",
    "    tool_calls = state[-1].additional_kwargs.get(\"tool_calls\", [])\n",
    "    multiply_call = None\n",
    "    for tool_call in tool_calls:\n",
    "        if tool_call.get(\"function\").get(\"name\") == \"multiply\":\n",
    "            multiply_call = tool_call\n",
    "    if multiply_call is None:\n",
    "        raise Exception(\"No adder input found.\")\n",
    "    res = multiply.invoke(\n",
    "        json.loads(multiply_call.get(\"function\").get(\"arguments\"))\n",
    "    )\n",
    "    return ToolMessage(\n",
    "        tool_call_id=multiply_call.get(\"id\"),\n",
    "        content=res\n",
    "    )\n",
    "graph.add_node(\"multiply\", invoke_tool)\n",
    "graph.add_edge(\"multiply\", END)\n",
    "graph.set_entry_point(\"oracle\")\n",
    "\n",
    "def router(state: List[BaseMessage]):\n",
    "    tool_calls = state[-1].additional_kwargs.get(\"tool_calls\", [])\n",
    "    if len(tool_calls):\n",
    "        return \"multiply\"\n",
    "    else:\n",
    "        return \"end\"\n",
    "\n",
    "graph.add_conditional_edges(\"oracle\", router, {\n",
    "    \"multiply\": \"multiply\",\n",
    "    \"end\": END,\n",
    "})\n",
    "runnable = graph.compile()\n",
    "\n",
    "# 把这个图打印出来\n",
    "from IPython.display import Image, display\n",
    "display(Image(runnable.get_graph().draw_mermaid_png()))\n",
    "\n",
    "response = runnable.invoke(HumanMessage(\"What is 123 * 456?\"))\n",
    "print(response[1].content)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
